package com.ssrs.platform.util;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.ssrs.platform.config.ResourceRoot;
import com.ssrs.platform.model.CommonFileUploadDTO;
import org.springframework.web.multipart.MultipartFile;

import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Date;

/**
 * 文件上传工具类
 *
 * @author ssrs
 */
public class FileUploadUtil {


    /**
     * 确保循环生成id时不重复
     *
     * @return
     */
    private static synchronized String getRandowId() {
        return IdUtil.fastSimpleUUID();
    }

    /**
     * 文件上传
     *
     * @param fie
     * @return
     */
    public static CommonFileUploadDTO upload(String baseDir, MultipartFile fie) throws IOException {
        String path = ResourceRoot.getValue();
        CommonFileUploadDTO result = new CommonFileUploadDTO();
        if (fie == null) {
            result.setFlag(false);
            result.setMessage("文件不能为空");
            return result;
        }
        String suffix = FileUtil.getSuffix(fie.getOriginalFilename());
        String fileName = baseDir + "/" + DateUtil.format(new Date(), "yyyy/MM/dd/") + getRandowId() + "." + suffix;
        return upload(fie.getInputStream(), path, fileName, false);
    }


    /**
     * 文件上传
     *
     * @param fie
     * @return
     */
    public static CommonFileUploadDTO upload(String baseDir, File fie) {
        String path = ResourceRoot.getValue();
        CommonFileUploadDTO result = new CommonFileUploadDTO();
        if (fie == null) {
            result.setFlag(false);
            result.setMessage("文件不能为空");
            return result;
        }
        String suffix = FileUtil.getSuffix(fie);
        String fileName = baseDir + "/" + DateUtil.format(new Date(), "yyyy/MM/dd/") + getRandowId() + "." + suffix;
        BufferedInputStream inputStream = FileUtil.getInputStream(fie);
        return upload(inputStream, path, fileName, false);
    }


    public static CommonFileUploadDTO upload(InputStream inputStream, String path, String fileName, boolean rewrite) {
        CommonFileUploadDTO result = new CommonFileUploadDTO();

        String fullName = path + fileName;
        File diskFile = new File(fullName);
        if (!FileUtil.exist(diskFile.getParentFile())) {
            FileUtil.mkdir(diskFile.getParentFile());
        }
        if (!rewrite && diskFile.exists()) {
            result.setFlag(false);
            result.setMessage("文件已经存在");
            return result;
        }
        FileUtil.mkParentDirs(diskFile);
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(diskFile);
            IoUtil.copy(inputStream, fileOutputStream);
            fileOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IoUtil.close(inputStream);
            IoUtil.close(fileOutputStream);
        }
        result.setFlag(true);
        result.setAbsolutePath(fullName);
        result.setFileName(fileName);
        result.setPreviewPath("/preview/" + fileName);
        return result;
    }


    /**
     * 图片上传
     *
     * @param file 上传文件
     * @return
     */
    public static CommonFileUploadDTO uploadImage(String baseDir, MultipartFile file) {
        return uploadImage(baseDir, file, null);
    }

    /**
     * 图片上传
     *
     * @param file       上传文件
     * @param dimensions 生成多张缩略图，格式：100,100;200,200
     * @return
     */
    public static CommonFileUploadDTO uploadImage(String baseDir, MultipartFile file, String dimensions) {
        String path = ResourceRoot.getValue();
        String fileName = baseDir + "/" + DateUtil.format(new Date(), "yyyy/MM/dd/") + getRandowId();
        return uploadImage(file, path, fileName, false, dimensions);
    }


    /**
     * 图片上传
     *
     * @param file       上传文件
     * @param path       根路径
     * @param fileName   子路径
     * @param rewrite    是否重写
     * @param dimensions 生成多张缩略图，格式：100,100;200,200
     * @return
     */
    public static CommonFileUploadDTO uploadImage(MultipartFile file, String path, String fileName, boolean rewrite, String dimensions) {
        CommonFileUploadDTO result = new CommonFileUploadDTO();

        if (path == null) {
            path = FileUtil.normalize(ResourceRoot.getValue());
        }
        if (file == null) {
            result.setFlag(false);
            result.setMessage("文件不能为空");
            return result;
        }
        if (StrUtil.isEmpty(fileName)) {
            fileName = System.currentTimeMillis() + "";
        }
        String sourceFileName = file.getOriginalFilename();

        String ext = FileTypes.checkAndGetExt(sourceFileName, "jpg", "jpeg", "bmp", "png", "gif");
        if (ext == null) {
            result.setFlag(false);
            result.setMessage("只能上传\"jpg,jpeg,bmp,png,gif\"格式的图片");
            return result;
        }

        String suffix = FileUtil.getSuffix(sourceFileName);

        fileName = fileName + "." + suffix;
        String fullName = path + "/" + fileName;
        fullName = FileUtil.normalize(fullName);
        if (!FileUtil.exist(new File(fullName).getParentFile())) {
            FileUtil.mkdir(new File(fullName).getParentFile());
        }
        if (!rewrite && new File(fullName).exists()) {
            result.setFlag(false);
            result.setMessage("文件已经存在");
            return result;
        }

        try {
            File diskFile = new File(fullName);
            file.transferTo(diskFile);
            diskFile.setReadable(true, false);
        } catch (Exception e) {
            e.printStackTrace();
            result.setFlag(false);
            result.setMessage(e.getMessage());
            return result;
        }
        if (StrUtil.isNotEmpty(dimensions)) {
            String[] arr = StrUtil.splitToArray(dimensions, ";");
            for (String dim : arr) {
                if (dim.indexOf(",") > 0) {
                    String w = dim.substring(0, dim.indexOf(","));
                    String h = dim.substring(dim.indexOf(",") + 1);
                    if (NumberUtil.isInteger(w) && NumberUtil.isInteger(h)) {
                        String prefix = fullName.substring(0, fullName.lastIndexOf("."));
                        String toFileName = prefix + "_" + w + "_" + h + "." + ext;
                        try {
                            ImgUtil.scale(new File(fullName), new File(toFileName), Integer.parseInt(w), Integer.parseInt(h), null);
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                        } catch (Exception e) {
                            e.printStackTrace();
                            result.setFlag(false);
                            result.setMessage(e.getMessage());
                            return result;
                        }
                    }
                }
            }
        }

        result.setFlag(true);
        result.setAbsolutePath(fullName);
        result.setFileName(fileName);
        result.setPreviewPath("/preview/" + fileName);
        return result;
    }


    /**
     * 获取图片宽度
     *
     * @param file 图片文件
     * @return 宽度
     */
    public static int getImgWidth(MultipartFile file) {
        String suffix = FileUtil.getSuffix(file.getName());
        if (!isImage(suffix)) {
            return 0;
        }
        BufferedImage src = null;
        int ret = -1;
        try {
            src = javax.imageio.ImageIO.read(file.getInputStream());
            ret = src.getWidth(null); // 得到源图宽
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }


    /**
     * 获取图片高度
     *
     * @param file 图片文件
     * @return 高度
     */
    public static int getImgHeight(MultipartFile file) {
        String suffix = FileUtil.getSuffix(file.getName());
        if (!isImage(suffix)) {
            return 0;
        }
        BufferedImage src = null;
        int ret = -1;
        try {
            src = javax.imageio.ImageIO.read(file.getInputStream());
            ret = src.getHeight(null); // 得到源图高
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * 是否图片
     *
     * @param suffix
     * @return
     */
    public static final boolean isImage(String suffix) {
        int fileType = FileTypes.getFileType(suffix);
        return fileType == 1;
    }

    /**
     * 是否网络图片
     *
     * @param url
     * @return
     */
    public static final boolean isImageUrl(String url) {
        if (StrUtil.isEmpty(url) || !url.startsWith("http")) {
            return false;
        }
        String suffix = url.substring(url.lastIndexOf(".") + 1);
        if (isImage(suffix)) {
            return true;
        }
        return false;
    }
}
